import fs from 'fs';
import {Client} from 'ssh2';
import archiver from 'archiver';
import SftpClient from 'ssh2-sftp-client';
import chproc from 'child_process';
const DOMAIN_URL = 'https://dtm.lanbaozixun.com';

const remoteHost = '39.101.177.18'; // 替换为你的远程主机
const username = 'root'; // 替换为你的用户名
const password = '750190tkkmTKKM^'; // 替换为你的密码

const sftp = new SftpClient();

async function run() {
    try {
        console.log('正在项目缓存...');
        await rmCacheBuildDir();
        console.log('开始编译项目...');
        await buildH5();
        console.log('开始打包项目=>h5.zip')
        const zipFileName = await zipH5Dir();
        console.log('项目编译成功，开始连接SFTP....');
        await connectSFTP();
        console.log('SFTP连接成功，开始上传' + zipFileName + '到' + getServerMobileDir() + '目录');
        const serverZipFileName = await uploadFile(zipFileName);
        const cmd = `cd ${getServerMobileDir()} &&  rm -rf static uni_modules yixu  index.html && unzip -o ${serverZipFileName} && rm -f h5.zip`;
        console.log('上传成功，开始执行部署命令：' + cmd);
        sftp.end();
        const r = await execCommand(cmd);
        console.log('执行结果：', r.toString());

    } catch (e) {
        console.log(e);
    }
}

const getServerMobileDir = () => {
    return {
        'https://dtm.lanbaozixun.com': '/www/wwwroot/dongtaima/public/mobile',
        'https://dch.lanbaozixun.com': '/www/wwwroot/dch.lanbaozixun.com/public/mobile',
        'https://hzr.lanbaozixun.com': '/datas/www/wwwroot/huazhirong/public/mobile',
        'https://zckj.lanbaozixun.com': '/www/wwwroot/zckj.lanbaozixun.com/public/mobile',
        'https://lfs.lanbaozixun.com': '/datas/www/wwwroot/luofeisi/public/mobile',
        'https://dcjcsx.lanbaozixun.com': '/datas/www/wwwroot/duanchengjinchengshangxue/public/mobile',
    }[DOMAIN_URL]
};
async function buildH5() {
    return new Promise((resolve, reject) => {
        chproc.exec('cli open');
        const child = chproc.exec('cli publish --platform h5 --project 蓝豹');
        child.on('close', (code) => {
            if (code === 0) {
                resolve();
                console.log('打包成功..');
            }else{
                reject(code);
            }
        });
    })

}
async function rmCacheBuildDir() {
    const folderToDelete = './unpackage/dist/build/web';
    if(fs.existsSync(fs)){
        return fs.rmdirSync(folderToDelete, {recursive: true, force: true});
    }
    return Promise.resolve();
}
async function connectSFTP() {
    return sftp.connect({
        host: remoteHost,
        port: '22',
        username: username,
        password: password
    });
}
async function uploadFile(zipFileName) {
    let serverZipFileName = getServerMobileDir() + '/h5.zip';
    return new Promise((resolve, reject) => {
        sftp.put(zipFileName, serverZipFileName).then(() => resolve(serverZipFileName)).catch(reject);
    });
}
async function execCommand(command) {
    return new Promise((resolve, reject) => {
        const conn = new Client();
        conn.on('ready', () => {
            // 执行解压命令
            console.log('开始执行：', command)
            conn.exec(command, (err, stream) => {
                if (err) {
                    reject(err);
                    return;
                }
                stream.on('close', (code, signal) => {
                    conn.end();
                }).on('data', (data) => {
                    resolve(data);
                }).stderr.on('data', (data) => {
                    console.log('data', data.toString());
                    reject(data);
                });
            });
        }).connect({
            host: remoteHost,
            port: 22,
            username: username,
            password: password
        });
    })

}
async function zipH5Dir() {
    const sourceDir = './unpackage/dist/build/web/';
    const zipFile = './unpackage/dist/build/' + 'h5.zip';
    // 创建一个输出流，用于保存 ZIP 文件
    const output = fs.createWriteStream(zipFile);
    const archive = archiver('zip', {
        zlib: {level: 9} // 设置压缩级别
    });
    return new Promise((resolve, reject) => {
        // 监听 'close' 事件，表示打包完成
        output.on('close', () => {
            resolve(zipFile);
        });
        // 监听 'error' 事件
        archive.on('error', (err) => {
            reject(err);
        });
        // 将输出流连接到 archive
        archive.pipe(output);

        archive.directory(sourceDir, false);

        // 完成压缩
        archive.finalize();
    })
}

run();
